# Create your views here.
import json
import random
import re
from urllib.parse import urlencode

from django.conf import settings
from django.contrib.auth import login, authenticate, logout
from fdfs_client.client import Fdfs_client



from utils.response_code import RET
from lovehome.utils.login import LoginRequiredJsonMixin
from . import constants
from django_redis import get_redis_connection
from django import http
from django.shortcuts import render, redirect
from django.views import View

from libs.captcha.captcha import captcha
from users import TIME
from users.models import User
import logging

logger = logging.getLogger('django')


class RegisterView(View):
    def get(self, request):

        return render(request, 'register.html')

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')
        phonecode = json_dict.get('phonecode')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')

        if not all([mobile, phonecode, password, password2]):
            return http.HttpResponseForbidden('参数错误')

        if not re.match(r'1[3-9]\d{9}', mobile):
            return http.HttpResponseForbidden('手机号格式错误')

        if User.objects.filter(mobile=mobile).count() > 0:
            return http.HttpResponseForbidden('手机号已被注册')

        if not password == password2:
            return http.HttpResponseForbidden('密码不一致')

        redis_conn = get_redis_connection('smscode')

        sms = redis_conn.get(mobile)

        if not sms:
            return http.HttpResponseForbidden('短信验证码已过期')

        redis_conn.delete(mobile)
        redis_conn.delete(mobile + 'ichliebedich')

        if sms.decode() != phonecode:
            return http.HttpResponseForbidden('短信验证码错误')

        user = User.objects.create_user(
            username=mobile,
            mobile=mobile,
            password=password
        )

        login(request, user)

        response = http.JsonResponse({'errno': RET.OK,
                                      'errmsg': '注册成功'})
        # response = redirect('index.html')
        response.set_cookie('mobile', mobile, max_age=TIME.SET_COOKIE_TIME)

        return response


class ImagecodeView(View):
    def get(self, request):
        pre = request.GET.get('pre')
        cur = request.GET.get('cur')

        text, image = captcha.generate_captcha()

        try:
            redis_conn = get_redis_connection('imagecode')

            pre = redis_conn.get(pre)
            if pre:
                redis_conn.delete(pre)

            redis_conn.setex(cur, constants.IMAGE_CODE_EXPIRES, text)
        except Exception:
            return http.JsonResponse({'errno': RET.PARAMERR,
                                      'errmsg': '参数错误'})

        return http.HttpResponse(image, content_type='image/png')


class SmscodeView(View):
    def post(self, request):
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')
        image_code = json_dict.get('image_code')
        image_code_id = json_dict.get('image_code_id')

        redis_sms = get_redis_connection('smscode')
        num = redis_sms.get(mobile + 'ichliebedich')
        if num is not None:
            return http.JsonResponse({'ernos': RET.DATAEXIST,
                                      'errmsg': '短信验证码发送频繁'})

        if not all([mobile, image_code, image_code_id]):
            return http.HttpResponseForbidden('缺少必传参数')

        if not re.match('1[3-9]\d{9}', mobile):
            return http.HttpResponseForbidden('手机号格式不正确')

        redis_conn = get_redis_connection('imagecode')

        text = redis_conn.get(image_code_id)

        if text is None:
            return http.JsonResponse({'errno': RET.NODATA,
                                      'errmsg': '图形验证码已过期'})

        redis_conn.delete(image_code_id)

        if text.decode().lower() != image_code.lower():
            return http.JsonResponse({'errno': RET.DATAERR,
                                      'errmsg': '图形验证码错误'})

        sms = '%06d' % random.randint(0, 999999)
        print(sms)

        redis_sms.setex(mobile, constants.SMS_CODE_EXPIRES * 100, sms)
        redis_sms.setex(mobile + 'ichliebedich', constants.SMS_CODE_FLAG, 1)

        ccp = CCP()
        ccp.send_template_sms(mobile, [sms, constants.SMS_CODE_EXPIRES], 1)

        return http.JsonResponse({'errno': RET.OK,
                                  'errmsg': '短信发送成功'})


class IndexView(View):
    def get(self, request):

        return redirect('/static/html/index.html')


class LoginView(View):
    def get(self, request):

        return render(request, 'login.html')

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        mobile = json_dict.get('mobile')
        password = json_dict.get('password')

        if not all([mobile, password]):
            return http.HttpResponseForbidden('缺少必传参数')

        try:
            user = User.objects.get(mobile=mobile)
        except:
            return http.JsonResponse({
                'errno': RET.USERERR,
                'errmsg': "没有该用户"
            })

        if not user.check_password(password):
            return http.JsonResponse({
                'errno': RET.USERERR,
                'errmsg': "没有该用户"
            })

            # 状态保持
        login(request, user)

        response = http.JsonResponse({
            'errno': RET.OK,
            'errmsg': "登录成功"
        })
        response.set_cookie('mobile', mobile, max_age=TIME.SET_COOKIE_TIME)
        return response


class SessionView(View):
    def get(self,request):
        '''
        获取登录状态API
        :param request:
        :return:
        '''
        if request.user.is_authenticated:
            return http.JsonResponse({"errno": "0", "errmsg": "OK",
                                      "data": {"user_id": request.user.id,
                                               "name": request.user.username}})
        else:
            return http.JsonResponse({"errno": "4101", "errmsg": "未登录"})


class LogoutView(LoginRequiredJsonMixin, View):
    def delete(self, request):
        '''
        退出登录API
        :param request:
        :return:
        '''
        logout(request)
        response = http.JsonResponse({
            'code': RET.NODATA,
            'errmsg': '用户已退出'
        })
        response.delete_cookie('password')
        return response


class UserInfoView(View):

    def get(self, request):
        user = request.user
        # 2.返回用户信息
        data = {
            "name": user.username,
            "avatar_url": user.avatar_url,
            "mobile": user.mobile
        }
        return http.JsonResponse({'errno': RET.OK, 'errmsg': "OK", 'data': data})

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        name = json_dict.get('name')

        if not name:
            return http.HttpResponseForbidden('缺少参数')

        try:
            user = User.objects.get(username=request.user.username)
            user.username=name
            user.save()
        except Exception:
            return http.JsonResponse({'code': RET.DBERR, 'errmsg': '数据库保存出错'})

        return http.JsonResponse({'errno': RET.OK,
                                  'errmsg': 'OK'})


class ImageUp(LoginRequiredJsonMixin, View):
    def post(self, request):
        content = request.FILES.get('avatar', None)
        if content is None:
            return http.JsonResponse({'errno': RET.PARAMERR, 'errmsg': "参数错误"})

        try:
            client = Fdfs_client(settings.FDFS_CLIENT_CONF)
            result = client.upload_by_buffer(content.read())
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({'errno': RET.THIRDERR, 'errmsg': "上传图片错误"})

        file_id = result.get('Remote file_id')
        url = settings.FDFS_URL + file_id

        user = request.user
        user.avatar_url = url
        user.save()

        return http.JsonResponse({'errno': RET.OK, 'errmsg': "OK", 'data': {"avatar_url": url}})


def get_html_file(request, file_name):
    # 判断是否是网站的Logo，如果不是，添加前缀
    if file_name != "favicon.ico":
        file_name = "/static/html/" + file_name

    params = request.GET
    if params:
        result = urlencode(params)
        return redirect(file_name + '?{}'.format(result))

    return redirect(file_name)


def auth(request):
    return redirect('/static/html/auth.html')

class RealName(LoginRequiredJsonMixin, View):
    def get(self, request):
        user = request.user
        data={
            'real_name':user.real_name,
            'id_card':user.id_card
        }

        return http.JsonResponse({'errno': RET.OK, 'errmsg': "OK", 'data': data})

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        real_name = json_dict.get('real_name')
        id_card = json_dict.get('id_card')

        if not all([real_name, id_card]):
            return http.HttpResponseForbidden('缺少必传参数')

        if not re.match(r'^[\u4e00-\u9fa5]', real_name):
            return http.HttpResponseForbidden('请输入中文字符')

        if not re.match(r'^\d{17}[0-9xX]', id_card):
            return http.HttpResponseForbidden('身份证格式不对')
        try:
            user = request.user
            user.real_name = real_name
            user.save()
        except Exception as e:
            return http.JsonResponse({'code': RET.DBERR, 'errmsg': '数据库保存出错'})

        try:
            user = request.user
            user.id_card = id_card
            user.save()
        except Exception as e:
            return http.JsonResponse({'code': RET.DBERR, 'errmsg': '数据库保存出错'})
            # 4.返回

        data={
            'real_name': real_name,
            'id_card': id_card
        }
        return http.JsonResponse({"errno": "0",
                                  "errmsg": "OK",
                                  "data": data})


class MyView(View):
    def get(self, request):

        return render(request,'my.html')


class ProfileView(View):
    def get(self, request):

        return redirect('/static/html/profile.html')